
/**************************************************************
 * 
 * Copyright ? 2012，北京福富软件技术股份有限公司
 * All Rights Reserved.
 * ------------------------------------------------------------
 * 文件名称：IniFileReader.java
 * 文件摘要：ini文件的读取与设置工具类
 * 初始版本：V1.0.0
 * 初始作者：Linz
 * 完成日期：2012-02
 * 
 **************************************************************/
package com.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

/**************************************************************************
 * 
 * 类名：IniFileReader<br>
 * <br>
 * 功能：ini文件的读取与设置工具类<br>
 * <br>
 * 作者：Linz 2012-02<br>
 * <br>
 * 属性列表：<br>
 * 		private Hashtable<String, Properties> sections = new Hashtable<String, Properties>()<br>
 * 		private String currentSection<br>
 * 		private Properties currentProp<br>
 * 		private String filePath<br>
 * <br>
 * 方法列表：<br>
 * 		public synchronized void init() throws IOException, Exception<br>
 * 		public synchronized String getValue(String section, String pname)<br>
 * 		public synchronized void setValue(String section, String pname, String pvalue) throws Exception<br>
 * 		public synchronized void removeValue(String section, String pname) throws Exception<br>
 * 		public synchronized void addValue(String section, String pname, String pvalue) throws Exception
 * 		...<br>
 * <br>
 * 修改记录：<br>
 * 		日期				修改人			修改说明<br>
 * 
 **************************************************************************/
public class IniFileReader 
{
	private Hashtable<String, Properties> sections = new Hashtable<String, Properties>();		//段集合，对应关系为一个段对应该段下所有属性
	
	private String currentSection;										//当前段名称
	
	private Properties currentProp;										//属性集合，一个名称对应属性值
	
	private String filePath;											//ini文件路径
	
	
	/**************************************************************************
	 * 
	 * 函数名：public IniFileReader(String filePath) throws IOException, Exception<br>
	 * <br>
	 * 功能：构造函数<br>
	 * 		1.传入ini文件路径<br>
	 * 		2.初始化<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String filePath	-> 文件路径<br>
	 * <br>
	 * 返回值：<br>
	 * 		无<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public IniFileReader(String filePath)
	{
		this.filePath = filePath;
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public synchronized void init() throws IOException, Exception<br>
	 * <br>
	 * 功能：ini文件初始化<br>
	 * 		1.解析该ini文件<br>
	 * 		2.将相应的段及属性值保存起来<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String filePath	-> 文件路径<br>
	 * <br>
	 * 返回值：<br>
	 * 		无<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public synchronized void init() throws IOException, Exception
	{
		BufferedReader br = null;
		String line       = null;
		try 
		{
			br 			  = new BufferedReader(new FileReader(filePath)); 
			while ((line=br.readLine()) != null)
			{
				line = line.trim();										//去除头尾空格
				if (line.matches("\\[.*\\]"))							//如果匹配到[]，则该值为段的名称
				{
					currentSection = line.replaceFirst("\\[(.*)\\]", "$1");
					currentProp    = new Properties();
					sections.put(currentSection, currentProp);
				}
				else if (line.matches(".*=.*"))							//如果匹配到*=*，则拆分保存到properties中
				{
					if (currentProp!=null)
					{
						int index 	  = line.indexOf("=");
						String pname  = line.substring(0, index);		//属性名称
						String pvalue = line.substring(index+1);		//属性值
						currentProp.put(pname.trim(), pvalue.trim());	//将这对属性保存至currentProp中
					}
				}
			}
		}
		catch (Exception e)
		{
			throw e;
		}
		finally
		{
			if (br!=null)	br.close();
		}
	}
	
	
	
	/**************************************************************************
	 * 
	 * 函数名：public synchronized String getValue(String section, String pname)<br>
	 * <br>
	 * 功能：根据段名与参数名，得到参数值<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String section	-> 段名称<br>
	 * 		String pname    -> 属性名称<br>
	 * <br>
	 * 返回值：<br>
	 * 		无<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public synchronized String getValue(String section, String pname)
	{
		Properties props = (Properties)sections.get(section);
		if (props!=null)
		{
			return props.getProperty(pname);
		}
		return null;
	}
	
	
	
	/**************************************************************************
	 * 
	 * 函数名：public synchronized void setValue(String section, String pname, String pvalue)<br>
	 * <br>
	 * 功能：根据段名称，参数名称，设置相应的参数值<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String section	-> 段名称<br>
	 * 		String pname    -> 属性名称<br>
	 * 		String pvalue	-> 属性值<br>
	 * <br>
	 * 返回值：<br>
	 * 		无<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public synchronized void setValue(String section, String pname, String pvalue) throws Exception
	{
		BufferedReader br   = null;
		String currSection  = "";			//当前段的名称 
		String line         = null;			//读取流的行内容
		String newLine		= null;			//替换后的新行内容
		String fileText     = "";			//文件内容
		boolean isInSection = false;		//是否在当前段内
		try 
		{
			br = new BufferedReader(new FileReader(filePath));
			while ((line=br.readLine())!=null)
			{
				line = line.trim();
				if (line.matches("\\[.*\\]"))									//匹配到段
				{
					currSection = line.replaceFirst("\\[(.*)\\]", "$1");		//当前段名称
					if (currSection.equals(section))
					{
						isInSection = true;
					}
					else
					{
						isInSection = false;
					}
				}
				if (isInSection)
				{
					if (line.matches(pname+"=.*"))			//匹配到属性名称
					{
						newLine       = pname+"="+pvalue;
						fileText     += newLine + "\r\n";
						while ((line=br.readLine())!=null)
						{
							fileText += line + "\r\n";
						}
						//回写文件
						BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, false));
						bufferedWriter.write(fileText);
						bufferedWriter.flush();
						return;
					}
				}
				fileText += line + "\r\n";		//文件内容累加
			}
		}
		catch (Exception e)
		{
			throw e;
		}
		finally
		{
			if (br!=null)	br.close();
			init();
		}
	}
	
	
	
	/**************************************************************************
	 * 
	 * 函数名：public synchronized void removeValue(String section, String pname, String pvalue)<br>
	 * <br>
	 * 功能：根据段名称，参数名称，清除该配置值<br>
	 * <br>
	 * 作者：Linz 2011-07-28<br>
	 * <br>
	 * 参数表：<br>
	 * 		String section	-> 段名称<br>
	 * 		String pname    -> 属性名称<br>
	 * <br>
	 * 返回值：<br>
	 * 		无<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public synchronized void removeValue(String section, String pname) throws Exception
	{
		BufferedReader br   = null;
		String currSection  = "";			//当前段的名称 
		String line         = null;			//读取流的行内容
		String newLine		= null;			//替换后的新行内容
		String fileText     = "";			//文件内容
		boolean isInSection = false;		//是否在当前段内
		try 
		{
			br = new BufferedReader(new FileReader(filePath));
			while ((line=br.readLine())!=null)
			{
				line = line.trim();
				if (line.matches("\\[.*\\]"))									//匹配到段
				{
					currSection = line.replaceFirst("\\[(.*)\\]", "$1");		//当前段名称
					if (currSection.equals(section))
					{
						isInSection = true;
					}
					else
					{
						isInSection = false;
					}
				}
				if (isInSection)
				{
					if (line.matches(pname+"=.*"))			//匹配到属性名称
					{
						newLine       = "";
						fileText     += newLine;
						while ((line=br.readLine())!=null)
						{
							fileText += line + "\r\n";
						}
						//回写文件
						BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, false));
						bufferedWriter.write(fileText);
						bufferedWriter.flush();
						return;
					}
				}
				fileText += line + "\r\n";		//文件内容累加
			}
		}
		catch (Exception e)
		{
			throw e;
		}
		finally
		{
			if (br!=null)	br.close();
			init();
		}
	}
	
	
	
	/**************************************************************************
	 * 
	 * 函数名：public synchronized void addValue(String section, String pname, String pvalue)<br>
	 * <br>
	 * 功能：根据段名称，参数名称，参数值，添加新的配置值<br>
	 * <br>
	 * 作者：Linz 2011-07-28<br>
	 * <br>
	 * 参数表：<br>
	 * 		String section	-> 段名称<br>
	 * 		String pname    -> 属性名称<br>
	 * 		String pvalue	-> 属性值<br>
	 * <br>
	 * 返回值：<br>
	 * 		无<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public synchronized void addValue(String section, String pname, String pvalue) throws Exception
	{
		BufferedReader br   = null;
		String currSection  = "";			//当前段的名称 
		String line         = null;			//读取流的行内容
		String newLine		= null;			//替换后的新行内容
		String fileText     = "";			//文件内容
		boolean isInSection = false;		//是否在当前段内
		try 
		{
			br = new BufferedReader(new FileReader(filePath));
			while ((line=br.readLine())!=null)
			{
				line = line.trim();
				if (line.matches("\\[.*\\]"))									//匹配到段
				{
					currSection = line.replaceFirst("\\[(.*)\\]", "$1");		//当前段名称
					if (currSection.equals(section))
					{
						isInSection = true;
					}
					else
					{
						isInSection = false;
					}
				}
				if (isInSection)
				{
					if ("".equals(line))
					{
						newLine		 = pname+"="+pvalue + "\r\n";
						fileText	+= newLine + "\r\n";
						while ((line=br.readLine())!=null)
						{
							fileText += line + "\r\n";
						}
						//回写文件
						BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, false));
						bufferedWriter.write(fileText);
						bufferedWriter.flush();
						return;
					}
				}
				fileText += line + "\r\n";		//文件内容累加
			}
		}
		catch (Exception e)
		{
			throw e;
		}
		finally
		{
			if (br!=null)	br.close();
			init();
		}
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public synchronized List<String> getKeyList(String section)<br>
	 * <br>
	 * 功能：根据段名，取得该段下的所有参数名集合<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String section	-> 段名称<br>
	 * <br>
	 * 返回值：<br>
	 * 		List -> 集合<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public synchronized List<String> getKeyList(String section)
	{
		Properties prop = sections.get(section);
		if (prop==null)
		{
			return null;
		}
		
		List<String> outList = new ArrayList<String>();
		Enumeration<Object> enm = prop.keys();
		while (enm.hasMoreElements())
		{
			String str = (String)enm.nextElement();
			if (str!=null && !"".equals(str))
			{
				outList.add(str);
			}
		}
		return outList;
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public synchronized List<String> getValueList(String section)<br>
	 * <br>
	 * 功能：根据段名，取得该段下的所有参数值集合<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String section	-> 段名称<br>
	 * <br>
	 * 返回值：<br>
	 * 		List -> 集合<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public synchronized List<String> getValueList(String section)
	{
		Properties prop = sections.get(section);
		if (prop==null)
		{
			return null;
		}
		
		List<String> outList = new ArrayList<String>();
		Collection<Object> col = prop.values();
		Iterator<Object>   it  = col.iterator();
		while (it.hasNext())
		{
			String str = (String)it.next();
			if (str!=null && !"".equals(str))
			{
				outList.add(str);
			}
		}
		return outList;
	}

}
